import "../../lib/ramda.js";
import "../../lib/jquery.js";
import direct2d from "../../lib/direct2d.js";
import game from "./game.js";
import utils from "../../lib/utils.js";

const Consts = {
    PC_PAGEWIDTH_RATE: 0.55,
    template: {
        pbox: $("ux-template#pbox").html(),
    },
}

const State = {
    _frame_fns: [],
    _event_quene: [],
}

function frame_join(fn) {
    State._frame_fns.push(fn)
}

function event_push(name, val) {
    State._event_quene.push([name,val])
}

function event_poll(name) {
    const i = R.findIndex((a)=>(a[0] == name), State._event_quene)
    return {
        on(fn){
            if (i >= 0) {
                const val = State._event_quene[i][1]
                const fn_take = ()=>{
                    if (State._event_quene.length > 1) {
                        State._event_quene[i] = State._event_quene.at(-1)
                    }
                    if (State._event_quene.length > 0) {
                        State._event_quene.pop()
                    }
                }
                fn(val, fn_take)
            }
        }
    }
}

function game_status(dom, io_fns) {
    frame_join(()=>{
        const count_str = `○ ${io_fns.n_black()} | ● ${io_fns.n_white()}`
        let pcur_str = (io_fns.pcur() == game.PIECE_BLACK) ? "→○" : "→●"
        if (io_fns.has_over()){
            const max_piece = io_fns.max_piece()
            if (max_piece == game.PIECE_EMPTY) {
                pcur_str = "DRAW"
            } else if (max_piece == game.PIECE_BLACK) {
                pcur_str = "○WIN"
            } else if (max_piece == game.PIECE_WHITE) {
                pcur_str = "●WIN"
            }
        }
        dom.html(`${pcur_str} (${count_str})`)
    })
}

function ai_status(dom, io_fns) {
    frame_join(()=>{
        const str = (io_fns.ai_in_think() ? io_fns.ai_status() : `${io_fns.ai_engine_name()}`)
        const [said_pcur, said_text] = io_fns.ai_said()
        const ai_pcur = (io_fns.ai_in_think() ? io_fns.pcur() : (said_text.length > 0 ? said_pcur : game.PIECE_EMPTY))
        const pcur_str = ((ai_pcur == game.PIECE_EMPTY) ? "" : ((ai_pcur == game.PIECE_BLACK) ? ":○" : ":●"))
        const said = (said_text.length > 0) ? ` ${said_text}` : ""
        dom.html(`[AI${pcur_str}${said}] ${str}`)
    })
}

function game_area(dom, io_fns) {
    const dom_pboxs = []
    for (const row of R.range(1, 11)) {
        const row_pboxs = []
        for (const col of R.range(1, 11)) {
            const html = Consts.template.pbox.replace("[ROW]", row).replace("[COL]", col)
            dom.append(html)
            dom_pboxs.push(dom.children().last())
        }
    }

    frame_join(()=>{
        event_poll("tap-piece").on((loc,fn_take)=>{
            io_fns.on_tap_piece(loc)
            fn_take()
        })
        io_fns.for_board((loc, p, can_down)=>{
            const dom = dom_pboxs[loc]
            if (can_down) {
                dom.removeClass("pbox-black").removeClass("pbox-white").addClass("pbox-can-down")
                dom.children().hide()
            } else {
                dom.removeClass("pbox-can-down")
                if (p == game.PIECE_EMPTY) {
                    dom.removeClass("pbox-black").removeClass("pbox-white")
                } else if (p == game.PIECE_BLACK) {
                    dom.removeClass("pbox-white").addClass("pbox-black")
                } else if (p == game.PIECE_WHITE) {
                    dom.removeClass("pbox-black").addClass("pbox-white")
                }
                dom.children().hide()
                const record_top = io_fns.record_top()
                if (record_top.loc() == loc) {
                    dom.children().html(`${record_top.step()}`).show()
                }
            }
        })
    })
}

function game_tools(io_fns) {
    const use_ai_black = $("#use-ai-black")
    const use_ai_white = $("#use-ai-white")
    use_ai_black.on("click", function(){
        io_fns.ai_player_set(game.PIECE_BLACK, $(this).prop("checked"))
    })
    use_ai_white.on("click", function(){
        io_fns.ai_player_set(game.PIECE_WHITE, $(this).prop("checked"))
    })

    const sel_num = (name)=>{
        direct2d.Option($(`#sel-${name}`), {
            on_select(val){
                io_fns.ai_param_set(name, Number(val))
            }
        }).select_with_eq(String(io_fns.ai_param(name)))
    }
    sel_num("uct-times")
    const sel_extra = direct2d.Option($("#sel-extra"), {
        on_select(val){
            const dom = $("#sel-extra").children(`[ux-value="${val}"]`)
            const param = dom.attr("param")
            if (R.is(String,param)) {
                io_fns.ai_param_set(param, Number(val))
            } else {
                io_fns.extra(val)
                sel_extra.select_with_eq(String(io_fns.ai_param("level")))
            }
        }
    }).select_with_eq(String(io_fns.ai_param("level")))
    if (! io_fns.kvs.bool("extra-test")) {
        $("#sel-extra").children("[test-only]").hide()
    }

    frame_join(()=>{
        if (use_ai_black.prop("checked") != io_fns.ai_player(game.PIECE_BLACK)) {
            use_ai_black.prop("checked", io_fns.ai_player(game.PIECE_BLACK))
        }
        if (use_ai_white.prop("checked") != io_fns.ai_player(game.PIECE_WHITE)) {
            use_ai_white.prop("checked", io_fns.ai_player(game.PIECE_WHITE))
        }
    })
}

function on_frame() {
    R.forEach(R.applyTo(undefined), State._frame_fns)
}

function events(io_fns) {
    $(".pbox").on("click", function(e){
        const dom = $(e.target)
        const y = Number(dom.css("grid-row").split(' ')[0]) - 1
        const x = Number(dom.css("grid-column").split(' ')[0]) - 1
        const loc = y * game.BOARD_SIZE + x
        event_push("tap-piece", loc)
    })
    $("#cmd-reset").on("click", function(){
        io_fns.on_cmd_reset()
    })
    $("#cmd-undo").on("click", function(){
        io_fns.on_cmd_undo()
    })
    $("#cmd-redo").on("click", function(){
        io_fns.on_cmd_redo()
    })
    $("#cmd-load-first").on("click", function(){
        io_fns.on_cmd_load_first()
    })
    $("#cmd-load-last").on("click", function(){
        io_fns.on_cmd_load_last()
    })
    window.addEventListener('beforeunload', (e)=>{
        e.preventDefault()
    })
    window.addEventListener('unload', (e)=>{
        io_fns.on_reload()
        e.preventDefault()
    })
}

function init(io_fns) {
    if ("pc" == direct2d.adaption_mobile_width(Consts.PC_PAGEWIDTH_RATE)) {
    }
    game_status($("#game-status"), io_fns)
    ai_status($("#ai-status"), io_fns)
    game_area($("#game-area"), io_fns)
    game_tools(io_fns)
    events(io_fns)
}

export default {
    init,
    on_frame,
}
